import IEntity from "../Interfaces/IEntity";
import EventDefines from "../Constants/EventDefines";
import Oriented from "../Constants/Oriented";
import G from "../Utilities/Global";
import Constants from "../Constants/Constants";
import Bullet from "./Bullet";
import eWeaponState from "../Constants/WeaponState";
import FsMachine from "../Lib/StateMachine/Fsmachine";
import AnimationController from "../Controllers/AnimationController";
import eState from "../Lib/StateMachine/eState";
import EntityGroup from "../Constants/EntityGroup";
import C from "../Configs/Config";
import PlayerMoveController from "../Controllers/PlayerMoveController";

/**
 * 玩家
 * created by Five on 2018-11-13 10:53:15
 */

const { ccclass, property } = cc._decorator;

@ccclass
export default class MainPlayer extends cc.Component implements IEntity {
    Group: EntityGroup = EntityGroup.PLAYER;

    private _moveController: PlayerMoveController = null;

    // 武器状态
    private _weaponState: eWeaponState = eWeaponState.NORMAL;

    public Fsm: FsMachine = null;

    public Dead:boolean = false;

    die() {
        // this.Fsm.ChangeState(eState.DYING);
        this.Dead = true;
    }

    public setAnim(anim: AnimationController) {
        this.Fsm = new FsMachine(anim);
    }

    public setMove(move: PlayerMoveController) {
        this._moveController = move;
    }

    // 设置武器
    public SetWeapon(ws: eWeaponState) {
        this._weaponState = ws;
    }

    update() {
        if (this.Fsm != null)
            this.Fsm.Tick();
    }

    // 碰撞
    onBeginContact(contact, self, other) {
        // 铁头 超过中轴, 大于头部
        let yVerify = other.node.position.y > this.node.position.y + Constants.ENTITY_EDGE - 10;
        let xVerify = Math.abs(other.node.position.x - this.node.position.x) < Constants.ENTITY_EDGE * 0.6;
        if (yVerify && xVerify) {
            var event = new cc.Event.EventCustom(EventDefines.EVENT_IRONHEAD, true);
            event.setUserData(other);
            this.node.dispatchEvent(event);
        }
        // 拾取/死亡之类的 撞到了扔给别人处理吧,跟咱没关系
        var event = new cc.Event.EventCustom(EventDefines.EVENT_PLAYER_CONTACT, true);
        event.setUserData([this, other]);
        this.node.dispatchEvent(event);
        let entity = G().CurScene.MapData.GetWallByPosition(other.node.position);
        // 脚底踩到才停
        let fVerify = other.node.position.y + Constants.ENTITY_EDGE * 0.8 < this.node.position.y;
        cc.log(other.node.position + " " + this.node.position);
        if (entity && fVerify) {
            // 撞到或踩到东西了，玩家退出跳跃状态
            if (G().MainPlayer.Fsm.CurrentState == eState.JUMP) {
                G().MainPlayer.Fsm.Execute();
            }
        }
    }

    // 攻击
    public async shot(oriented: Oriented) {
        // if (this._weaponState != eWeaponState.NORMAL) {
        let bullet = await G().Res.GetRes(Constants.PRE_BULLET) as cc.Node;
        let pos = this.node.position;
        // 子父关系节点
        bullet.position = this.node.position.addSelf(G().Calc.FW(pos, oriented));
        bullet.addComponent(Bullet).SetDir(oriented);
        bullet.getComponent(Bullet).SetNavigater(this._weaponState);
        bullet.getComponent(Bullet).SetOwner(this);
        bullet.getComponent(Bullet).SetLifeTime(10);
        this.node.parent.addChild(bullet);
        // }else{
        //     cc.log("TODO 近战武器")
        // }
    }

    public makeOrdestroy(ori: Oriented, sqaut: boolean) {
        let position = this.node.position;
        let edge = Constants.ENTITY_EDGE;
        position.x += ori == Oriented.RIGHT ? edge : -edge;
        position.y += sqaut ? -edge / 2 : 0;
        // if(sqaut)


        let event = new cc.Event.EventCustom(EventDefines.PLAY_TILEEDIT, true);
        event.setUserData(position);
        this.node.dispatchEvent(event);
    }

    public Attack() {
        this._moveController.makeOrdestory();
    }

    public sqautMake() {
        this._moveController.sqautMake();
    }

    public jump() {
        this._moveController.jump();
    }

    public move(left: boolean) {
        this._moveController.move(left);
    }

    public stop() {
        this._moveController.stop();
    }
}